<template>
  <swiper class="m-tiktok-video-swiper" :circular="false" @change="handleSwiperChange" :current="currentIndex" :vertical="true" duration="300">
    <swiper-item v-for="(item, index) in videoList" :key="item.id || index">
      <view class="swiper-item" @click="handleClick">
        <video
          class="m-tiktok-video-player"
          :src="item.file || item.src"
          :id="`video__${index}`"
          :controls="controls"
          :show-center-play-btn="controls"
          :object-fit="item.objectFit || 'cover'"
          :autoplay="false"
          :loop="loop"
          :custom-cache="false"
          @ended="handleVideoEnded"
          @controlstoggle="handleControlsToggle"
          @play="handleVideoPlay"
          @error="handleVideoError"
          @loadedmetadata="handleVideoLoaded($event, item)"
        ></video>

        <!-- 自定义播放按钮 -->
        <view class="m-tiktok-video-play-btn" v-if="!controls && currentIndex === index" @click="togglePlay">
          <text class="m-tiktok-video-iconfont video-icon" :class="{ active: !isPlaying }"> &#xe607; </text>
        </view>

        <!-- 视频封面 -->
        <image v-if="item.poster && currentIndex !== index" :src="item.poster" class="m-tiktok-video-poster" mode="aspectFit"></image>

        <!-- 插槽内容 -->
        <slot :item="item" :index="index" :isActive="currentIndex === index"></slot>
      </view>
    </swiper-item>
  </swiper>
</template>

<script setup>
  import { ref, watch, getCurrentInstance, onUnmounted } from 'vue';

  const _this = getCurrentInstance();

  const emits = defineEmits(['play', 'error', 'loadMore', 'change', 'controlstoggle', 'click', 'ended']);

  const props = defineProps({
    /**
     * 视频列表
     */
    videoList: {
      type: Array,
      default: () => [],
    },
    /**
     * 是否循环播放单个视频
     */
    loop: {
      type: Boolean,
      default: true,
    },
    /**
     * 显示原生控制栏
     */
    controls: {
      type: Boolean,
      default: false,
    },
    /**
     * 是否自动播放
     */
    autoplay: {
      type: Boolean,
      default: true,
    },
    /**
     * 是否自动切换到下一个视频
     */
    autoChange: {
      type: Boolean,
      default: false,
    },
    /**
     * 滚动加载阈值（距离底部多少个时触发加载更多）
     */
    loadMoreOffset: {
      type: Number,
      default: 2,
    },
    /**
     * 视频自动自适应平铺模式
     */
    autoObjectFit: {
      type: Boolean,
      default: true,
    },
  });

  // 响应式数据
  const currentIndex = ref(0);
  const isPlaying = ref(false);
  const videoContexts = ref([]);

  // 初始化视频上下文
  const initVideoContexts = () => {
    videoContexts.value = props.videoList.map((_, index) => uni.createVideoContext(`video__${index}`, _this));
  };

  // 播放指定索引的视频
  const playVideo = (index) => {
    if (!props.autoplay) return;

    // 停止所有视频
    videoContexts.value.forEach((context) => context?.stop());

    // 延迟播放当前视频
    setTimeout(() => {
      const context = videoContexts.value[index];
      if (context) {
        context.play();
        isPlaying.value = true;
      }
    }, 300);
  };

  // 处理swiper滑动
  const handleSwiperChange = (event) => {
    const newIndex = event.detail.current;

    if (newIndex === currentIndex.value) return;

    currentIndex.value = newIndex;

    // 触发change事件
    const currentItem = props.videoList[newIndex];
    if (currentItem) {
      emits('change', { index: newIndex, item: currentItem });
    }

    // 播放当前视频
    playVideo(newIndex);

    // 检查是否需要加载更多
    checkLoadMore(newIndex);
  };

  // 检查是否需要加载更多数据
  const checkLoadMore = (index) => {
    const totalCount = props.videoList.length;
    const remainingCount = totalCount - index - 1;

    if (remainingCount <= props.loadMoreOffset) {
      emits('loadMore');
    }
  };

  // 切换播放/暂停
  const togglePlay = () => {
    const context = videoContexts.value[currentIndex.value];
    if (!context) return;

    if (isPlaying.value) {
      context.pause();
      isPlaying.value = false;
    } else {
      context.play();
      isPlaying.value = true;
    }
  };

  // 跳转到指定时间
  const seekTo = (time) => {
    const context = videoContexts.value[currentIndex.value];
    if (context) {
      context.seek(time);
    }
  };

  // 事件处理函数
  const handleVideoPlay = (event) => {
    isPlaying.value = true;
    emits('play', event);
  };

  const handleVideoEnded = (event) => {
    isPlaying.value = false;

    // 自动切换到下一个视频
    if (props.autoChange && currentIndex.value < props.videoList.length - 1) {
      currentIndex.value++;
      playVideo(currentIndex.value);
    }

    emits('ended', event);
  };

  const handleVideoError = (event) => {
    emits('error', event);
  };

  const handleControlsToggle = (event) => {
    emits('controlstoggle', event);
  };

  const handleClick = (event) => {
    emits('click', event);
  };

  const handleVideoLoaded = (event, item) => {
    if (!props.autoObjectFit || item.objectFit) return;

    // 自动设置视频平铺模式
    const { width, height } = event.detail;
    if (width < height) {
      // 竖屏视频，全覆盖
      item.objectFit = 'cover';
    } else {
      // 横屏视频，居中显示
      item.objectFit = 'contain';
    }
  };

  // 监听视频列表变化
  watch(
    () => props.videoList,
    (newList) => {
      if (newList && newList.length > 0) {
        // 重新初始化视频上下文
        setTimeout(() => {
          initVideoContexts();
          // 播放第一个视频
          if (currentIndex.value === 0) {
            playVideo(0);
          }
        }, 100);
      }
    },
    { immediate: true },
  );

  // 监听当前索引变化（已在handleSwiperChange中触发change事件，此处不再重复触发）
  // watch(currentIndex, (newIndex) => {
  //   const currentItem = props.videoList[newIndex];
  //   if (currentItem) {
  //     emits('change', { index: newIndex, item: currentItem });
  //   }
  // });

  // 组件卸载时清理
  onUnmounted(() => {
    videoContexts.value.forEach((context) => context?.stop());
  });

  // 暴露方法
  defineExpose({
    togglePlay,
    seekTo,
    playVideo,
    getCurrentIndex: () => currentIndex.value,
    getCurrentItem: () => props.videoList[currentIndex.value],
  });
</script>

<style lang="scss">
  @font-face {
    font-family: 'm-tiktok-play-icon';
    src: url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAJ0AA0AAAAABlgAAAIiAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCQhEICkhaCwoAATYCJAMQBCAFhQIHLxt4BcieBXbLR4jiyygbC791Mg0vz9JsPPz/ft/2ufeMmCQP9fXfRhxvMKHjkcSsTkqWplJJqpFFfn79mr4NG5fvwujI+EPeZCbudGJcy6oVklRVp8IAdgMJUqD853ceuhm3iSafWxNoC0bbskAmUGABTlrDAgwsC+xJ3/SJf3DecLgpCpyFgDcXlRJ8uiufSVcHBjENilBVIVGQKS50UZ6U1+ApeD7+6kcvRVcl2fZub1Q8/BfJG9VHbUp9J0UAYBWhomIRgUZWYFHOKkgp+FFsyVvmRkB0E4AooAg/DwF/49FSQIJeBMbBDIAEQIzfDW+OPVHX48vXUy26fUwfJnN0+tW5bLx3+dz5fHT61rQEIBDc77r579ZI8793IDWgftfb8/q83gC9Cggqvex6gvqcDoBMGojkOvpX4wgU9OtHC2DcOwgwoYpA6LWDQNHjDgJVr8cCpF7PBOgy4JUA3Xq9BYF+29EgMGAiLlSRfVgDlgyjlmQx7JSsRgVQYkeyy7RLstuoF7Lfid+qAWtxbiWmkbDEVgmyA2hRBHx6jOEomxtSuCEvAg5k/U4c0Bh2XJIYfiwLaz88BE9oYgkrKPS0dWGtk7/X7rqFOsU+TZzFM4k9Qx9jOkEXC3iErR+f0LhcASEUC9g0CtaGY3Jrsjf6zPrqiLsTyi1RpN9z3wPOMRaa6+jQAzbblCgVWLpySeZmOVzvLw8uOfSjoLSEEiV7Yg==)
      format('woff2');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
  }

  .m-tiktok-video-iconfont {
    font-family: m-tiktok-play-icon;
  }

  .m-tiktok-video-swiper,
  .m-tiktok-video-player {
    width: 100%;
    height: 100vh;
    background-color: #000;
  }

  .m-tiktok-video-swiper {
    .swiper-item {
      position: relative;
    }

    .m-tiktok-video-poster {
      background-color: #000;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }

    .m-tiktok-video-play-btn {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1;
      display: flex;
      align-items: center;
      justify-content: center;

      .video-icon {
        font-size: 50px;
        display: block;
        color: rgba(255, 255, 255, 0.8);
        opacity: 0;
        transition: opacity 0.3s ease;

        &.active {
          opacity: 1;
        }
      }
    }
  }
</style>